package com.htstar.ovms.report.service.impl;


import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.htstar.ovms.admin.api.entity.EtpInfo;
import com.htstar.ovms.admin.api.feign.EtpInfoFeign;
import com.htstar.ovms.admin.api.vo.EtpInfoSVo;
import com.htstar.ovms.common.core.util.OvmDateUtil;
import com.htstar.ovms.common.core.util.R;
import com.htstar.ovms.common.core.util.WebUtils;
import com.htstar.ovms.common.security.service.OvmsUser;
import com.htstar.ovms.common.security.util.SecurityUtils;
import com.htstar.ovms.report.api.req.ByMonthReportReq;
import com.htstar.ovms.report.api.req.ByMonthReportReqNoPage;
import com.htstar.ovms.report.api.req.ByMonthReportReqPage;
import com.htstar.ovms.report.api.vo.*;
import com.htstar.ovms.report.mapper.DeviceAlarmReportMapper;
import com.htstar.ovms.report.service.DeviceAlarmReportService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class DeviceAlarmReportServiceImpl implements DeviceAlarmReportService {

    @Autowired
    DeviceAlarmReportMapper deviceAlarmReportMapper;

    @Autowired
    EtpInfoFeign etpInfoFeign;

    @Override
    public R<OnlineRateReportVO> onlineMonth(ByMonthReportReq req) {
        Integer etpId = SecurityUtils.getUser().getEtpId();
        if (req.getEtpId() == null || "".equals(req.getEtpId())) {
            req.setEtpId(etpId);
        }
        //获取该企业下的后代企业ids
        List<EtpInfoSVo> currentAndParents1 = etpInfoFeign.getCurrentAndParents1(req.getEtpId());
        EtpInfoSVo etpInfoSVo = currentAndParents1.get(0);
        List<Integer> ids = etpInfoSVo.getIds();
        req.setEtpIds(ids);
//        //单独查询车牌的情况
//        if (req.getLicCode() != null && !"".equals(req.getLicCode())) {
//            return onlineMonthBylic(req);
//        }
        //计算总的在线率与在线数
        //当前在线数
        OnlineRateReportVO rsVO = new OnlineRateReportVO();
        Integer onlineCount = deviceAlarmReportMapper.onlineCount(req);//今年的总在线数，参数：年
        rsVO.setTotalOnline(onlineCount == null ? "0" : onlineCount.toString());
        Integer carCount = deviceAlarmReportMapper.AllCarCount(req);
        if (onlineCount != null && onlineCount > 0 && carCount != null && carCount > 0) {
            rsVO.setTotalOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(onlineCount, carCount).doubleValue()));
        } else {
            rsVO.setTotalOnlineRate("0.00");
        }
        ArrayList<OnlineVO> dataVOS = new ArrayList<>();
        //计算每月的数据
        String yearDate = req.getYearDate();
        StringBuffer monthShort = new StringBuffer(yearDate);
        for (int i = 1; i < 13; i++) {
            monthShort = new StringBuffer(yearDate);
            if (i < 10) {
                monthShort.append("-").append("0").append(i);
            } else {
                monthShort.append("-").append(i);
            }
            req.setYearDate(monthShort.toString());
            Integer count = deviceAlarmReportMapper.onlineCount(req);
            OnlineVO onlineVO = new OnlineVO();
            onlineVO.setMonth(monthShort.toString());
            onlineVO.setOnlineCount(count);
            if (count != null && count > 0 && carCount != null && carCount > 0) {
                onlineVO.setOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(count, carCount).doubleValue()));
            }
            List<EtpInfo> rs = deviceAlarmReportMapper.getEtpName(req.getEtpId());
            onlineVO.setEtpName(rs.get(0).getEtpName());
            dataVOS.add(onlineVO);
        }
        rsVO.setDataVOS(dataVOS);

        if (req.getExportStatus() == 1) {
            return onlineMonthExport(rsVO);
        }
        return R.ok(rsVO);
    }

    private R<OnlineRateReportVO> onlineMonthBylic(ByMonthReportReq req) {
        Integer etpId = SecurityUtils.getUser().getEtpId();
        //计算该车该年在线天数
        Integer onlineCount = deviceAlarmReportMapper.onlineCountByLic(req);
        OnlineRateReportVO rsVO = new OnlineRateReportVO();
        if (onlineCount != null && onlineCount > 0) {
            rsVO.setTotalOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(onlineCount, Integer.valueOf(365)).doubleValue()));
        } else {
            rsVO.setTotalOnlineRate("0.00");
            return R.ok(rsVO);
        }

        ArrayList<OnlineVO> dataVOS = new ArrayList<>();
        //计算每月的数据
        int monDay = 0;
        String yearDate = req.getYearDate();
        StringBuffer monthShort = new StringBuffer(yearDate);
        for (int i = 1; i < 13; i++) {
            monthShort = new StringBuffer(yearDate);
            if (i < 10) {
                monthShort.append("-").append("0").append(i);
            } else {
                monthShort.append("-").append(i);
            }
            req.setYearDate(monthShort.toString());
            Integer count = deviceAlarmReportMapper.onlineCountByLic(req);
            OnlineVO onlineVO = new OnlineVO();
            onlineVO.setMonth(monthShort.toString());
            onlineVO.setOnlineCount(count);
            if (i == 1) {
                monDay = 31;
            } else if (i == 2) {
                monDay = 28;
            } else if (i == 3) {
                monDay = 31;
            } else if (i == 4) {
                monDay = 30;
            } else if (i == 5) {
                monDay = 31;
            } else if (i == 6) {
                monDay = 30;
            } else if (i == 7) {
                monDay = 31;
            } else if (i == 8) {
                monDay = 31;
            } else if (i == 9) {
                monDay = 30;
            } else if (i == 10) {
                monDay = 31;
            } else if (i == 11) {
                monDay = 30;
            } else if (i == 12) {
                monDay = 31;
            }
            if (count != null && count > 0) {
                onlineVO.setOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(count, Integer.valueOf(monDay)).doubleValue()));
            }
            List<EtpInfo> rs = deviceAlarmReportMapper.getEtpName(req.getEtpId());
            onlineVO.setEtpName(rs.get(0).getEtpName());
            dataVOS.add(onlineVO);
        }
        rsVO.setDataVOS(dataVOS);

        if (req.getExportStatus() == 1) {
            return onlineMonthExport(rsVO);
        }
        return R.ok(rsVO);
    }

    private R<OnlineRateReportVO> onlineMonthExport(OnlineRateReportVO rsVO) {
        //报表输出
        HttpServletResponse response = WebUtils.getResponse();
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.renameSheet("报表信息");

        List<Map<String, Object>> totalrows = new ArrayList<>();
        Map<String, Object> row1 = new LinkedHashMap<>();
        row1.put("车辆上线数总计", rsVO.getTotalOnline());
        row1.put("车辆上线率", rsVO.getTotalOnlineRate());
        totalrows.add(row1);

        writer.write(totalrows, true);
        List<Map<String, Object>> rows = new ArrayList<>();
        for (OnlineVO vo : rsVO.getDataVOS()) {
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("月份", vo.getMonth());
            row.put("机构名称", vo.getEtpName());
            row.put("车辆上线数", vo.getOnlineCount());
            row.put("车辆上线率", vo.getOnlineRate());
            rows.add(row);
        }
        writer.write(rows, true);
        OutputStream out = null;
        try {
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(URLEncoder.encode(
                    "上线率报表-按月统计" + OvmDateUtil.getCstNowDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
                    , "UTF-8").getBytes("UTF-8"), "ISO8859-1") + ".xlsx");
            out = response.getOutputStream();
            writer.flush(out, true);
        } catch (
                IOException e) {
            log.error("用车报表-按月统计", e);
        } finally {
            writer.close();
            IoUtil.close(out);
            return null;
        }
    }

    @Override
    public R<OnlineRateReportVO> onlineCar(ByMonthReportReq req) {
        Integer etpId = SecurityUtils.getUser().getEtpId();
        String etpName = deviceAlarmReportMapper.getEtpName(etpId).get(0).getEtpName();
        if (req.getEtpId() == null || "".equals(req.getEtpId())) {
            req.setEtpId(etpId);
        }
        //获取该企业下的后代企业ids
        List<EtpInfoSVo> currentAndParents1 = etpInfoFeign.getCurrentAndParents1(req.getEtpId());
        EtpInfoSVo etpInfoSVo = currentAndParents1.get(0);
        List<Integer> ids = etpInfoSVo.getIds();
        req.setEtpIds(ids);

        if (req.getExportStatus() == 1) {
            return exportOnlineCar(req);
        }

        ByMonthReportReqPage pageReq = new ByMonthReportReqPage();
        BeanUtils.copyProperties(req, pageReq);

        //时间处理
        String[] st = req.getStaTime().split(" ");
        LocalDate staTime = LocalDate.parse(st[0], DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(req.getEndTime().split(" ")[0], DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Period between1 = Period.between(staTime, endTime);
        long days = between1.getDays() + 1;

        //计算总的在线率与在线数
        OnlineRateReportVO rsVO = new OnlineRateReportVO();
        ByMonthReportReqNoPage allTotal = new ByMonthReportReqNoPage();
        BeanUtils.copyProperties(req, allTotal);
        Integer onlineCount = deviceAlarmReportMapper.onlineCountNoPage(allTotal);//时间区间总在线数，参数：年 //今年 企业及后代 所有在车在线次数
        rsVO.setTotalOnline(onlineCount == null ? "0" : onlineCount.toString());
        Integer carCount = deviceAlarmReportMapper.AllCarCountNoPage(allTotal);//企业下的总车数
        if (onlineCount != null && onlineCount > 0 && carCount != null && carCount > 0) {
            rsVO.setTotalOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(onlineCount, carCount).doubleValue()));
        } else {
            rsVO.setTotalOnlineRate("0.00");
        }

        //空字串处理
        if ("".equals(pageReq.getLicCode())) {
            pageReq.setLicCode(null);
        }
        IPage<OnlineVO> rs = deviceAlarmReportMapper.onlineCarReport(pageReq);
        for (OnlineVO r : rs.getRecords()) {
            if (r.getOnlineCount() == null || "0".equals(r.getOnlineCount())) {
                r.setOnlineRate("0.00");
            } else {
                r.setOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(r.getOnlineCount(), new BigDecimal(days)).doubleValue()));
            }
        }
        rsVO.setPageList(pageReq);
        return R.ok(rsVO);
    }

    private R<OnlineRateReportVO> exportOnlineCar(ByMonthReportReq req) {
        //计算总的在线率与在线数
        OnlineRateReportVO rsVO = new OnlineRateReportVO();
        Integer onlineCount = deviceAlarmReportMapper.onlineCount(req);//今年的总在线数，参数：年
        if (onlineCount == null) {
            onlineCount = 0;
        }
        rsVO.setTotalOnline(onlineCount == null ? "0" : onlineCount.toString());
        Integer carCount = deviceAlarmReportMapper.AllCarCount(req);
        if (onlineCount != null && onlineCount > 0 && carCount != null && carCount > 0) {
            rsVO.setTotalOnlineRate(NumberUtil.decimalFormatMoney(NumberUtil.div(onlineCount, carCount).doubleValue()));
        } else {
            rsVO.setTotalOnlineRate("0.00");
        }

        //时间处理
        String[] st = req.getStaTime().split(" ");
        LocalDate staTime = LocalDate.parse(st[0], DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(req.getEndTime().split(" ")[0], DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Period between1 = Period.between(staTime, endTime);
        long days = between1.getDays() + 1;

        //空字串处理
        if ("".equals(req.getLicCode())) {
            req.setLicCode(null);
        }

        //SQL查询
        List<OnlineVO> rs = deviceAlarmReportMapper.onlineCarReportNoPage(req);
        if (rs == null || rs.isEmpty()) {
            return R.ok();
        }
        //报表输出
        HttpServletResponse response = WebUtils.getResponse();
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.renameSheet("报表信息");

        List<Map<String, Object>> totalrows = new ArrayList<>();
        Map<String, Object> row1 = new LinkedHashMap<>();
        row1.put("车辆上线数总计", rsVO.getTotalOnline());
        row1.put("车辆上线率", rsVO.getTotalOnlineRate());
        totalrows.add(row1);

        writer.write(totalrows, true);
        List<Map<String, Object>> rows = new ArrayList<>();
        for (OnlineVO vo : rs) {
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("车辆", vo.getLicCode());
            row.put("机构名称", vo.getEtpName());
            row.put("车辆上线率", vo.getOnlineRate());
            rows.add(row);
        }
        writer.write(rows, true);
        OutputStream out = null;
        try {
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(URLEncoder.encode(
                    "上线率报表-按车统计" + OvmDateUtil.getCstNowDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
                    , "UTF-8").getBytes("UTF-8"), "ISO8859-1") + ".xlsx");
            out = response.getOutputStream();
            writer.flush(out, true);
        } catch (
                IOException e) {
            log.error("用车报表-按车统计", e);
        } finally {
            writer.close();
            IoUtil.close(out);
            return null;
        }
    }

    private void timeTypeHandler(ByMonthReportReq req) {
        if (Integer.valueOf(0).equals(req.getTimeType())) {//查询当天
            String staTime = req.getStaTime();
        }

    }

    @Override
    public OverSpeedReportVO overSpeedByMonth(ByMonthReportReq req) {
        return null;
    }

    @Override
    public OverSpeedReportVO overSpeedByCar(ByMonthReportReq req) {
        return null;
    }

    @Override
    public OverSpeedReportVO overSpeedByPerson(ByMonthReportReq req) {
        return null;
    }

    @Override
    public BorderReportVO borderByMonth(ByMonthReportReq req) {
        return null;
    }

    @Override
    public BorderReportVO borderByCar(ByMonthReportReq req) {
        return null;
    }

    @Override
    public BorderReportVO borderByPerson(ByMonthReportReq req) {
        return null;
    }
}
